package java;

/**
 * double check 懒汉模式 （DCL）
 * 缺点：避免的上面方式的明显缺点，但是java内存模型（jmm）并不限制处理器重排序，在执行instance=new Singleton()；时，并不是原子语句，实际是包括了下面三大步骤：
 * 1.为对象分配内存
 * 2.初始化实例对象
 * 3.把引用instance指向分配的内存空间
 * 这个三个步骤并不能保证按序执行，处理器会进行指令重排序优化，存在这样的情况：
 * 优化重排后执行顺序为：1,3,2, 这样在线程1执行到3时，instance已经不为null了，线程2此时判断instance!=null，则直接返回instance引用，但现在实例对象还没有初始化完毕，此时线程2使用instance可能会造成程序崩溃。
 * 现在要解决的问题就是怎样限制处理器进行指令优化重排。
 */
public class Singleton5 {

    private static Singleton5 instance;

    private Singleton5() {
    }

    public static Singleton5 getInstance() {

        if (instance == null) {
            synchronized (Singleton5.class) {
                if (instance == null) {
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
}